// 验证 Zig 标准库替换是否成功
// 这个文件测试所有核心模块是否能正常编译和工作

const cz_std = @import("src/cz_std.zig");
const array_list = @import("src/array_list.zig");
const lexer = @import("src/lexer.zig");
const parser = @import("src/parser.zig");
const codegen = @import("src/codegen.zig");

pub fn main() !void {
    // 注意：这里仍然使用 std 来获取 allocator，因为这是系统级功能
    const std = @import("std");
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    
    std.debug.print("=== CZ 编译器标准库替换验证 ===\n\n", .{});
    
    // 测试 1: cz_std 字符串操作
    std.debug.print("[1/6] 测试 cz_std 字符串操作...\n", .{});
    try testCzStdStrings();
    std.debug.print("  ✅ 通过\n\n", .{});
    
    // 测试 2: cz_std 数字解析
    std.debug.print("[2/6] 测试 cz_std 数字解析...\n", .{});
    try testCzStdParsing();
    std.debug.print("  ✅ 通过\n\n", .{});
    
    // 测试 3: ArrayList
    std.debug.print("[3/6] 测试 ArrayList...\n", .{});
    try testArrayList(allocator);
    std.debug.print("  ✅ 通过\n\n", .{});
    
    // 测试 4: StringBuilder
    std.debug.print("[4/6] 测试 StringBuilder...\n", .{});
    try testStringBuilder(allocator);
    std.debug.print("  ✅ 通过\n\n", .{});
    
    // 测试 5: Lexer
    std.debug.print("[5/6] 测试 Lexer...\n", .{});
    try testLexer(allocator);
    std.debug.print("  ✅ 通过\n\n", .{});
    
    // 测试 6: Parser
    std.debug.print("[6/6] 测试 Parser...\n", .{});
    try testParser(allocator);
    std.debug.print("  ✅ 通过\n\n", .{});
    
    std.debug.print("=== 所有测试通过！✅ ===\n", .{});
    std.debug.print("\n核心模块已成功替换 Zig 标准库！\n", .{});
}

fn testCzStdStrings() !void {
    // 测试字符串相等
    if (!cz_std.eql("hello", "hello")) return error.TestFailed;
    if (cz_std.eql("hello", "world")) return error.TestFailed;
    
    // 测试字符串查找
    if (cz_std.indexOf("hello world", "world")) |pos| {
        if (pos != 6) return error.TestFailed;
    } else {
        return error.TestFailed;
    }
    
    // 测试 startsWith
    if (!cz_std.startsWith("hello", "hel")) return error.TestFailed;
    if (cz_std.startsWith("hello", "world")) return error.TestFailed;
    
    // 测试 endsWith
    if (!cz_std.endsWith("hello", "llo")) return error.TestFailed;
    if (cz_std.endsWith("hello", "world")) return error.TestFailed;
}

fn testCzStdParsing() !void {
    // 测试整数解析
    const num = try cz_std.parseInt(i64, "12345", 10);
    if (num != 12345) return error.TestFailed;
    
    const neg_num = try cz_std.parseInt(i64, "-999", 10);
    if (neg_num != -999) return error.TestFailed;
    
    // 测试浮点数解析
    const fnum = try cz_std.parseFloat(f64, "123.45");
    if (fnum < 123.44 or fnum > 123.46) return error.TestFailed;
    
    const neg_fnum = try cz_std.parseFloat(f64, "-99.9");
    if (neg_fnum > -99.8 or neg_fnum < -100.0) return error.TestFailed;
}

fn testArrayList(allocator: cz_std.Allocator) !void {
    var list = array_list.ArrayList(i32).init(allocator);
    defer list.deinit();
    
    try list.append(1);
    try list.append(2);
    try list.append(3);
    
    if (list.items.len != 3) return error.TestFailed;
    if (list.items[0] != 1) return error.TestFailed;
    if (list.items[1] != 2) return error.TestFailed;
    if (list.items[2] != 3) return error.TestFailed;
}

fn testStringBuilder(allocator: cz_std.Allocator) !void {
    var sb = cz_std.StringBuilder.init(allocator);
    defer sb.deinit();
    
    try sb.append("Hello");
    try sb.append(" ");
    try sb.append("World");
    
    if (!cz_std.eql(sb.items(), "Hello World")) return error.TestFailed;
    if (sb.len() != 11) return error.TestFailed;
}

fn testLexer(allocator: cz_std.Allocator) !void {
    const source = "fn main() { return 42; }";
    const tokens = try lexer.tokenize(allocator, source);
    defer allocator.free(tokens);
    
    // 应该至少有几个 token
    if (tokens.len < 5) return error.TestFailed;
    
    // 第一个应该是 fn 关键字
    if (tokens[0].type != .keyword_fn) return error.TestFailed;
}

fn testParser(allocator: cz_std.Allocator) !void {
    const source = "fn add(a: i32, b: i32) -> i32 { return a; }";
    const tokens = try lexer.tokenize(allocator, source);
    defer allocator.free(tokens);
    
    const ast = try parser.parse(allocator, tokens);
    defer ast.deinit(allocator);
    
    // 应该至少有一个节点
    if (ast.items.len < 1) return error.TestFailed;
    
    // 第一个节点应该是函数声明
    if (ast.items[0] != .function_decl) return error.TestFailed;
}
